from rest_framework import serializers
from util.typing import RestFrameWorkModelSerializerTyping
from apps.user.models import *
from django.contrib.auth.models import Permission, Group


class UserModelSerializers(serializers.ModelSerializer):
    class Meta(RestFrameWorkModelSerializerTyping):
        model = User
        fields = ('id', 'username', 'last_login')


class UserListSerializers(serializers.ModelSerializer):
    permissions = serializers.SerializerMethodField()
    parent_user = serializers.SerializerMethodField()

    def get_parent_user(self, row):
        if row.parent_user:
            return {
                'username': row.parent_user.username,
                'id': row.parent_user.id
            }
        else:
            return {}

    def get_permissions(self, row: User):
        if row.is_superuser:
            permissions = Permission.objects.all()
        else:
            permissions = row.get_all_permissions()
            permissions = Permission.objects.filter(codename__in=permissions)
        return PermissionSerializers(instance=permissions, many=True).data

    class Meta(RestFrameWorkModelSerializerTyping):
        model = User
        # fields = '__all__'
        exclude = ['password', 'user_permissions', ]
        depth = 1

    def create(self, validated_data):
        request = self.context['request']
        groups_id = request.data.get('groups', [])
        instance: User = User.objects.create_user(
            password=request.data['password'],
            **validated_data
        )
        instance.parent_user_id = request.user.id
        groups = Group.objects.filter(id__in=groups_id)
        for i in groups:
            instance.groups.add(i)
        instance.save()
        return instance

    def update(self, instance, validate_data):
        request = self.context['request']
        instance: User = super().update(instance, validate_data)
        if request.data['password']:
            instance.set_password(request.data['password'])
        groups_id = request.data.get('groups', [])
        groups = Group.objects.filter(id__in=groups_id)
        for i in groups:
            instance.groups.add(i)
        instance.save()
        return instance


class PermissionSerializers(serializers.ModelSerializer):

    class Meta:
        model = Permission
        exclude = ['content_type']


class UserInfoModelSerializers(serializers.ModelSerializer):
    permissionList = serializers.SerializerMethodField()
    permissions = serializers.SerializerMethodField()

    def get_permissionList(self, row):
        return list(row.get_all_permissions())

    def get_permissions(self, row: User):
        if row.is_superuser:
            permissions = Permission.objects.all()

        else:
            permissions = row.get_all_permissions()
            permissions = Permission.objects.filter(codename__in=permissions)
        return PermissionSerializers(instance=permissions, many=True).data

    class Meta(RestFrameWorkModelSerializerTyping):
        model = User
        fields = ('id', 'username', 'last_login', 'permissions',
                  'is_superuser', 'permissionList', 'avatar')


class GroupModelSerializers(serializers.ModelSerializer):
    group_id = serializers.IntegerField(source="id", read_only=True)

    class Meta(RestFrameWorkModelSerializerTyping):
        model = Group
        fields = "__all__"
        depth = 1

    def create(self, validated_data):
        request = self.context['request']
        per = request.data.get('permissions', [])
        instance = super().create(validated_data)
        print(validated_data, instance)
        permissions: Group = Permission.objects.filter(id__in=per)
        instance.permissions.clear()
        instance.permissions.add(*permissions)
        return instance

    def update(self, instance, validated_data):
        instance = super().update(instance, validated_data)
        request = self.context['request']
        per = request.data.get('permissions', [])
        permissions: Group = Permission.objects.filter(id__in=per)
        instance.permissions.clear()
        instance.permissions.add(*permissions)
        return instance
